package main

import (
	"fmt"
	"strconv"
	"unsafe"
)

func main() {
	var a int

	fmt.Println(a)                // 0	默认0
	fmt.Println(unsafe.Sizeof(a)) // 8	打印字节大小
	fmt.Printf("%T", a)           // int	打印所属数据类型
	fmt.Println()

	// 定义字符型数据
	var b byte = 'a'
	fmt.Println(b) // 97
	var b2 byte = '6'
	fmt.Println(b2) // 54
	var b3 byte = '('
	fmt.Println(b3)      // 40
	fmt.Println(b3 + 20) // 60 可以参与运算

	var b4 int = '中'
	fmt.Println(b4) // 20013
	var b5 byte = 'A'
	fmt.Println("b5对应的字符是: ", b5) // 65

	// 转义字符
	// \n 换行
	fmt.Println("aaa\nbbb")
	// \b 退格
	fmt.Println("aaa\bbbb") // aabbb
	// \r 光标回到本行开头,会替换原有字符
	fmt.Println("aaaaaaa\rbbb") // bbb
	// \t 制表符
	fmt.Println("aaaaa\tbbb") // aaaaa	bbb

	// 布尔类型
	var flag bool = true
	fmt.Println(flag) // true

	var flag2 bool = false
	fmt.Println(flag2) // false

	var flag3 bool = 5 < 9
	fmt.Println(flag3) // true 	因为5确实小于9

	// 字符串
	var s1 string = "hello,Golang"
	fmt.Println(s1) // hello,Golang
	// 字符串是不可变的,比如修改指定下标位置的字符
	//s1[1] = 'b'		// 不可以这样写

	// 如果有特殊字符,使用``,不是单引号,是ESC键下面的这个`键
	var s2 string = `fmt.Println(s1)`
	fmt.Println(s2) // fmt.Println(s1)

	// 字符拼接
	var s3 string = "abc" + "de"
	s3 += "fg"
	fmt.Println(s3) // abcdefg
	// 当字符拼接过长,把加号+ 留在最后一个,表示当前的一行还有
	var s4 string = "abc" + "defg" + "higj" + "lmn" +
		"opq" + "rst" + "uvw" + "xyz"
	fmt.Println(s4) // abcdefghigjlmnopqrstuvwxyz

	var aa int
	var bb float32
	var cc float64
	var dd bool
	var ee string
	fmt.Println(aa) // 0
	fmt.Println(bb) // 0
	fmt.Println(cc) // 0
	fmt.Println(dd) // false
	fmt.Println(ee) //     空字符,啥也没打印

	// go里面都是强制类型转换
	var n1 int = 100
	//var n2 float32 = n1 // 这样直接编译报错
	var n2 float32 = float32(n1)
	fmt.Println(n2) // 100
	// n1还是int类型,只是值转为了float32
	fmt.Printf("%T", n1) // int
	fmt.Println()

	// int64转int8,大的转小的,不会编译报错,但是会数据溢出
	var n3 int64 = 88888888
	var n4 int8 = int8(n3)
	fmt.Println(n4) // 56

	// 小的转大的写法
	var n5 int32 = 12
	//var n6 int64 = n5 + 30	// 这样直接编译报错
	var n6 int64 = int64(n5) + 30
	fmt.Println(n6) // 42

	var n7 int64 = 12
	var n8 int8 = int8(n7) + 127
	//var n9 int8 = int8(n7) + 128	// 编译直接报错,超出了int8的范围
	fmt.Println(n8) //-117

	var nn1 int = 19
	var nn2 float32 = 4.78
	var nn3 bool = false
	var nn4 byte = 'a'
	var ss1 string = fmt.Sprintf("%d", nn1)
	fmt.Printf("ss1类型是: %T, ss1 = %q   \n", ss1, ss1) // ss1类型是: string, ss1 = "19"
	var ss2 string = fmt.Sprintf("%f", nn2)
	fmt.Printf("ss2类型是: %T, ss2 = %q   \n", ss2, ss2) // ss2类型是: string, ss2 = "4.780000"
	var ss3 string = fmt.Sprintf("%t", nn3)
	fmt.Printf("ss3类型是: %T, ss3 = %q   \n", ss3, ss3) // ss3类型是: string, ss3 = "false"
	var ss4 string = fmt.Sprintf("%c", nn4)
	fmt.Printf("ss4类型是: %T, ss4 = %q   \n", ss4, ss4) // ss4类型是: string, ss4 = "a"

	var nnn1 int = 18
	// 参数1:必须转为int64, 参数2:指定面值为10进制
	var sss1 string = strconv.FormatInt(int64(nnn1), 10)
	fmt.Printf("sss1对应的类型是: %T, sss1 = %q \n", sss1, sss1) // sss1对应的类型是: string, sss1 = "18"
	var nnn2 float64 = 4.29
	// 参数2: 'f'表示格式（-ddd.dddd）,参数3: 保留小数点后9位, 参数4: 表示float64类型
	var sss2 string = strconv.FormatFloat(nnn2, 'f', 9, 64)
	fmt.Printf("sss2对应的类型是: %T, sss2 = %q \n", sss2, sss2) // sss2对应的类型是: string, sss2 = "4.290000000"
	var nnn3 bool = true
	var sss3 string = strconv.FormatBool(nnn3)
	fmt.Printf("sss3对应的类型是: %T, sss3 = %q \n", sss3, sss3) // sss3对应的类型是: string, sss3 = "true"

	var aaa1 string = "true"
	var bbb bool
	// ParseBool函数返回值有两个(value bool, err error)
	// 使用_ 过滤掉err
	bbb, _ = strconv.ParseBool(aaa1)
	fmt.Printf("bbb的类型是: %T, b = %v \n", bbb, bbb) // bbb的类型是: bool, b = true

	var aaa2 string = "19"
	var num1 int64
	// 参数2: 10进制, 参数3: 表示int64
	num1, _ = strconv.ParseInt(aaa2, 10, 64)
	fmt.Printf("num1的类型是: %T, num1 = %v \n", num1, num1) // num1的类型是: int64, num1 = 19

	var aaa3 string = "golang"
	var bbb2, _ = strconv.ParseBool(aaa3)
	fmt.Printf("bbb2的类型是: %T, bbb2 = %v \n", bbb2, bbb2) // bbb2的类型是: bool, bbb2 = false

	//var aaa4 string = "golang"
	//var num2 int64
	//nnn2, _ = strconv.ParseInt(aaa4, 10, 64)
	//fmt.Printf("num2的类型是: %T, num2 = %v", num2, num2)
}
